/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin		 	*/
/*	Project:	GlbLib-1.0.0			*/
/*	Author:		gong_libin			*/
/*	Date:		2016_06_01			*/
/*	File:		GlbMember.cpp			*/
/********************************************************/

#include "GlbMember.h"

namespace GlbCls
{

CGlbMember::CGlbMember()
{
	m_pKey = NULL;
	m_ucStatus = GLB_IDLE;
	pthread_cond_init(&m_stCond, NULL);
	pthread_mutex_init(&m_stLock, NULL);
}

CGlbMember::~CGlbMember()
{
	m_pKey = NULL;
	m_ucStatus = GLB_IDLE;
	pthread_cond_destroy(&m_stCond);
	pthread_mutex_destroy(&m_stLock);
}

int CGlbMember::GlbMemberAssign(void* pKey)
{
	int iReturn = GLB_FAILURE;

	GlbMemberLock();
	if (GLB_IDLE == m_ucStatus) {
		m_pKey = pKey;
		m_ucStatus = GLB_BUSY;
		GlbMemberUnlock();
		GlbMemberSignal();
		iReturn = GLB_SUCCESS;
	}
	else {
		GlbMemberUnlock();
	}

	return iReturn;
}

int CGlbMember::GlbMemberCreate()
{
	if (GLB_FAILURE == pthread_create(&m_iID, &m_stAttr, GlbMemberRoutine, this)) {
		GLB_ERROR("%s\n", strerror(errno));
		return GLB_FAILURE;
	}

	return GLB_SUCCESS;
}

void* GlbMemberRoutine(void* pSelf)
{
	while (true) {
		((CGlbMember*)pSelf)->GlbMemberLock();
		while (GLB_IDLE == ((CGlbMember*)pSelf)->GlbMemberStatusGet()) {
			((CGlbMember*)pSelf)->GlbMemberWait();
		}
		((CGlbMember*)pSelf)->GlbMemberUnlock();

		(*((CGlbMember*)pSelf)->GlbThreadRoutineGet())(((CGlbMember*)pSelf)->GlbMemberKeyGet());

		((CGlbMember*)pSelf)->GlbMemberLock();
		((CGlbMember*)pSelf)->GlbMemberStatusSet(GLB_IDLE);
		((CGlbMember*)pSelf)->GlbMemberKeySet(NULL);
		((CGlbMember*)pSelf)->GlbMemberUnlock();
	}

	pthread_exit(NULL);
}

} /* GlbCls */
